package cn.stylefeng.roses.kernel.ca.server.core.sso;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.stylefeng.roses.kernel.ca.api.CaClientTokenApi;
import cn.stylefeng.roses.kernel.ca.api.pojo.CaClientInfo;
import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi;
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.Set;

/**
 * 统一认证中心，客户端token管理的接口
 *
 * @author fengshuonan
 * @date 2022/5/20 10:22
 */
@Slf4j
public class CaClientTokenApiImpl implements CaClientTokenApi {

    /**
     * 客户端token的缓存
     */
    private final CacheOperatorApi<Set<CaClientInfo>> clientTokenCache;

    public CaClientTokenApiImpl(CacheOperatorApi<Set<CaClientInfo>> clientTokenCache) {
        this.clientTokenCache = clientTokenCache;
    }

    @Override
    public void addClientToken(String userCaToken, CaClientInfo caClientInfo) {
        Set<CaClientInfo> userClientInfos = clientTokenCache.get(userCaToken);
        if (ObjectUtil.isEmpty(userClientInfos)) {
            userClientInfos = new HashSet<>();
        }

        // 判断如果加过了就不添加到缓存
        for (CaClientInfo item : userClientInfos) {
            if (item.getClientId().equals(caClientInfo.getClientId())) {
                return;
            }
        }
        userClientInfos.add(caClientInfo);

        clientTokenCache.put(userCaToken, userClientInfos);
    }

    @Override
    public void logoutClientTokens(String userCaToken) {

        // 获取CAID对应的所有客户端Token
        Set<CaClientInfo> caClientTokens = clientTokenCache.get(userCaToken);

        // 对应客户端token为空
        if (ObjectUtil.isEmpty(caClientTokens)) {
            return;
        }

        // 逐个执行退出登录操作
        for (CaClientInfo caClientInfo : caClientTokens) {
            // 如果需要统一退出，则调用单点退出接口，将客户端对应登录的token下线
            if (YesOrNotEnum.Y.getCode().equals(caClientInfo.getUnifiedLogoutFlag())) {
                try {
                    HttpRequest httpRequest = HttpUtil.createGet(
                            caClientInfo.getSsoLogoutUrl() + "?caToken=" + userCaToken);
                    httpRequest.setConnectionTimeout(1000);
                    httpRequest.setReadTimeout(3000);
                    HttpResponse execute = httpRequest.execute();
                    log.info("退出单点客户端成功：clientId={},返回结果={}", caClientInfo.getClientId(), execute.body());
                } catch (Exception e) {
                    log.info("退出单点客户端失败：clientId={},错误信息={}", caClientInfo.getClientId(), e.getMessage());
                }
            }
        }
    }

}
